Linux libdrm库入门教程 您所在的位置:网站首页 what is drm Linux libdrm库入门教程

Linux libdrm库入门教程

2023-08-14 17:09| 来源: 网络整理| 查看: 265

DRM 相关知识链接

1、基础概念介绍: https://www.cnblogs.com/EaIE099/p/7514293.html

2、api接口说明: https://docs.nvidia.com/drive/nvvib_docs/NVIDIA%20DRIVE%20Linux%20SDK%20Development%20Guide/baggage/group__direct__rendering__manager.html

DRM库提供的测试工具

modetest用法: 在这里插入图片描述 1、查看状态信息,输入命令:modetest则显示如下信息(省略属性信息)

Encoders: id crtc type possible crtcs possible clones 60 59 DSI 0x00000001 0x00000000 Connectors: id encoder status name size (mm) modes encoders 61 60 connected DSI-1 68x121 1 60 modes: name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot) 720x1280 60 720 760 770 810 1280 1302 1306 1317 64000 flags: nhsync, nvsync; type: preferred CRTCs: id fb pos size 59 66 (0,0) (720x1280) 720x1280 60 720 760 770 810 1280 1302 1306 1317 64000 flags: nhsync, nvsync; type: preferred Planes: id crtc fb CRTC x,y x,y gamma size possible crtcs 58 59 66 0,0 0,0 0 0x00000001 formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 Frame buffers: id size pitch

上面含义是:

1 个connectors:id=61, 最大分辨率为720x1280;1 个crtc:id=59,最大分辨率为720x1280;1 个plane:id=58,支持像素格式 XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16。

比如使用RG24(对应RGB888,具体可参见drm_fourcc.h)像素格式测试屏幕显示:

modetest -s 61@59:720x1280@RG24

上述命令执行后的显示效果如下: 在这里插入图片描述

测试用例

工程下载地址:https://download.csdn.net/download/lyy901135/11588539

运行命令:mydrmtest 在这里插入图片描述

运行效果:先显示一个白屏(1s),然后显示30帧竖直黑白间隔图像(间隔1s)。如下图所示(手机翻拍导致不清晰) 在这里插入图片描述

代码说明:本示例基于RK1808,最大分辨率为720x1280,仅有一个Connector,一个Crtc,一个Plane。若针对多Plane平台,则还需动态适配显示模式,图像格式,图层等。

/* * Author:Francis Fan * Date:2019-8-21 */ #include #include #include #include #include #include #include #include #include #include #include #include "util/kms.h" #include "drm_fourcc.h" #include "buffers.h" #include "libdrm_macros.h" static void debug_save_file(void *ptr, int size, char *path) { FILE *debug_file; int ret = 0; debug_file = fopen(path, "wb"); if (!debug_file) { printf("DEBUG: open debug file %s failed!\n", path); return; } ret = fwrite(ptr, 1, size, debug_file); if (ret != size) printf("DEBUG: save debug file %s failed\n", path); else printf("DEBUG: save debug file as %s\n", path); fclose(debug_file); } /* Fill black and white vertical stripe data, like: * White | Black | White | Black */ static void fill_frame_rgb24_date(unsigned char *ptr, int width, int height, int linesize) { unsigned char *line_ptr = NULL; unsigned char d_r = 0, d_g = 0, d_b = 0; if (!ptr || (linesize line_ptr = ptr + i * linesize; for (int j = 0; j d_r = 0; d_g = 0; d_b = 0; } else if (j d_r = 0; d_g = 0; d_b = 0; } else { d_r = 255; d_g = 255; d_b = 255; } *line_ptr = d_r; line_ptr++; *line_ptr = d_g; line_ptr++; *line_ptr = d_b; line_ptr++; } } } int main(int argc, char *argv[]) { int frame_cnt = 30; int width, height; int ret = 0; int drm_fd = 0; int connector_id, crtc_id, plane_id; drmModeRes *res = NULL; drmModeConnector *conn = NULL; drmModeCrtc *crtc = NULL; drmModePlaneRes *pres = NULL; unsigned int fb_id; if (argc == 3) { width = atoi(argv[1]); height = atoi(argv[2]); printf("### Input Resolution:%sx%s --> (%d, %d)\n", argv[1], argv[2], width, height); } else { width = 720; height = 1280; printf("### Default Resolution: 720x1280\n"); } printf("### Init drm ...\n"); drm_fd = util_open(NULL, NULL); if (drm_fd printf("ERROR: drmModeGetCrtc failed!\n"); goto OUT; } res = drmModeGetResources (drm_fd); if (!res) { printf("ERROR: drmModeGetResources failed!\n"); drmClose(drm_fd); return -1; } printf("INFO: count_fbs:%d, count_crtcs:%d, count_encoders:%d, count_connectors:%d \n", res->count_fbs, res->count_crtcs, res->count_encoders, res->count_connectors); /* This test for only 1 connector and only 1 crtc */ connector_id = res->connectors[0]; crtc_id = res->crtcs[0]; /* Just fort print connector only */ conn = drmModeGetConnector (drm_fd, connector_id); if (!conn) { printf("ERROR: drmModeGetConnector failed!\n"); goto OUT; } /* Get plane infos */ pres = drmModeGetPlaneResources (drm_fd); if (!pres) { printf("ERROR: drmModeGetPlaneResources failed!\n"); goto OUT; } /* This test for only 1 plane */ plane_id = pres->planes[0]; printf("INFO: connector->name:%s-%u\n", util_lookup_connector_type_name(conn->connector_type), conn->connector_type_id); printf("INFO: connector id = %d / crtc id = %d / plane id = %d\n", connector_id, crtc_id, plane_id); /*********************************************************** * Start Mode Setting ***********************************************************/ struct bo *bo; drmModeModeInfo *mode; /* Max planes:4 * handles: dumb buffer handle, create by libdrm api * pitches: real linesize, by Bytes. * offset: every plane offset. */ unsigned int handles[4] = {0}; unsigned int pitches[4] = {0}; unsigned int offsets[4] = {0}; uint64_t cap = 0; /* Support dumb buffer? */ ret = drmGetCap(drm_fd, DRM_CAP_DUMB_BUFFER, &cap); if (ret || cap == 0) { fprintf(stderr, "ERROR: driver doesn't support the dumb buffer API\n"); goto OUT; } /* Create dumb buffer and mmap it */ bo = bo_create(drm_fd, DRM_FORMAT_RGB888, width, height, handles, pitches, offsets, UTIL_PATTERN_SMPTE); if (bo == NULL) { printf("ERROR: bo_create failed!\n"); goto OUT; } for (int i = 0; i ptr, 255, height * pitches[0]); /* Get framebuff id, this id is used by drm api to find the buffer. * Format the display memory, then the drm api knows what format to * display the memory of the drm application. */ ret = drmModeAddFB2(drm_fd, width, height, DRM_FORMAT_RGB888, handles, pitches, offsets, &fb_id, 0); if (ret) { printf("ERROR: drmModeAddFB2 failed!\n"); goto OUT; } /* Get the crtc display mode. For this test, only 1 mode support. */ mode = &conn->modes[0]; printf("INFO: mode->mame:%s, %dx%d, Conn_id:%d, crtc_id:%d\n", mode->name, mode->hdisplay, mode->vdisplay, connector_id, crtc_id); ret = drmModeSetCrtc(drm_fd, crtc_id, fb_id, 0, 0, (uint32_t *)&connector_id, 1, mode); if (ret) { printf("ERROR: drmModeSetCrtc failed!\n"); goto OUT; } /* XXX: Actually check if this is needed */ drmModeDirtyFB(drm_fd, fb_id, NULL, 0); /* show modeseting effect: full screen white */ sleep(1); /*********************************************************** * Start Set plane: show frame to plane ***********************************************************/ while (frame_cnt--) { fill_frame_rgb24_date(bo->ptr, width, height, pitches[0]); //debug_save_file(bo->ptr, pitches[0]*height); /* note src coords (last 4 args) are in Q16 format */ if (drmModeSetPlane(drm_fd, plane_id, crtc_id, fb_id, 0, 0, 0, width, height, 0, 0, width if (bo->ptr) drm_munmap(bo->ptr, bo->size); bo->ptr = NULL; bo_destroy(bo); } if (pres) drmModeFreePlaneResources (pres); if (conn) drmModeFreeConnector (conn); if (res) drmModeFreeResources (res); if (drm_fd) drmClose(drm_fd); return 0; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有